// tspcluster - Traveling Salesman Problem
// Copyright (C) 2006  Frederik Carlier
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Collections;
using System.Runtime.Serialization.Formatters;
using System.ServiceProcess;

namespace UGent.Tsp
{
    public class RemotingServer : ServiceBase
    {
        public RemotingServer()
        {
            this.ServiceName = "RemotingServer";
        }

        protected override void OnStart(string[] args)
        {
            SetUpServer();
        }

        // Standard port number is based upon the order of the letters
        // TSP in the alphabet.
        // T: 20
        // S: 19
        // P: 16
        //
        //       TTPP
        //       2016
        //        19
        //        SS
        //
        // Port  2206
        public const int DefaultPortNumber = 2206;

        public static void SetUpServer()
        {
            BinaryServerFormatterSinkProvider serverSinkProvider = new BinaryServerFormatterSinkProvider();
            serverSinkProvider.TypeFilterLevel = TypeFilterLevel.Full;

            BinaryClientFormatterSinkProvider clientSinkProvider = new BinaryClientFormatterSinkProvider();

            IDictionary properties = new Hashtable(1);
            properties["port"] = DefaultPortNumber;

            TcpChannel channel = new TcpChannel(properties, clientSinkProvider, serverSinkProvider);
            ChannelServices.RegisterChannel(channel, false);

            // Register as many Markov Chains as CPU's
            for (int i = 0; i < ComputerInfo.NumberOfProcessors; i++)
            {
                RemotingConfiguration.RegisterWellKnownServiceType(
                  typeof(MarkovChain), "MarkovChain" + i.ToString(), WellKnownObjectMode.Singleton);
            }

            // Register the ComputerInfo object, as to obtain information about this computer
            RemotingConfiguration.RegisterWellKnownServiceType(
                    typeof(ComputerInfo), "ComputerInfo", WellKnownObjectMode.SingleCall);
        }

        public static void RunOnConsole()
        {
            SetUpServer();

            Console.WriteLine("Press enter to exit.");
            Console.ReadLine();
        }
    }
}
